<?php
/**
 * @notes:
 * @return
 * @author: admin
 * @date: 2024/9/11
 */
namespace addons\shopro\service\tokens;

use addons\shopro\service\Wallet;
use addons\shopro\service\Wallet as WalletService;
use app\admin\model\shopro\tokens\Config;
use app\admin\model\shopro\tokens\Record;
use app\admin\model\shopro\tokens\Trade;
use app\admin\model\shopro\user\User;
use think\Db;
use think\Exception;

class TradeService
{

    protected $query = null;
    protected $format = null;

    public function __construct(\Closure $format = null, \think\db\Query $query = null)
    {
        $this->query = $query ?: new Trade();
        $this->relationSearch = true;
        $this->format = $format;
    }

    /***
     * 获取交易中心列表
     * @notes:
     * @param $user
     * @param $index
     * @return Trade|null
     * @throws \think\exception\DbException
     * @author: 小谢
     * @date: 2024/9/11 13:47
     */
    public function getList($user,$type)
    {
        $list=[];
        switch ($type){
            case 'buy':
                $list=$this->query->with(['buy'])->where(['trade.status'=>0,'trade.type'=>'buy'])->where('buy_uid','<>',$user->id)->order('createtime','DESC')->paginate(request()->param('list_rows', 10));
                foreach ($list as $row) {
                    $row->visible(['id','order_num','account','total_price','price','pay_time','createtime','status','type', 'wallet_type']);
                    $row->visible(['buy']);
                    $row->getRelation('buy')->visible(['nickname','avatar']);
                }
                break;
            case 'sell':
                $list=$this->query->with(['sale'])->where(['trade.status'=>0,'trade.type'=>'sell'])->where('sale_uid','<>',$user->id)->order('createtime','DESC')->paginate(request()->param('list_rows', 10));
                foreach ($list as $row) {
                    $row->visible(['id','order_num','account','total_price','price','pay_time','createtime','status','type', 'wallet_type']);
                    $row->visible(['sale']);
                    $row->getRelation('sale')->visible(['nickname','avatar']);
                }
                break;
            case 'my':
                $list=$this->query->with(['buy','sale'])->where(['trade.sale_uid|trade.buy_uid'=>$user['id']])->order('createtime','DESC')->paginate(request()->param('list_rows', 10));
                foreach ($list as $row) {
                    $row->visible(['id','order_num','account','total_price','price','pay_time','createtime','status','type', 'wallet_type']);
                    $row->visible(['sale']);
                    $row->getRelation('sale')->visible(['nickname','avatar']);
                    $row->visible(['buy']);
                    $row->getRelation('buy')->visible(['nickname','avatar']);
                }
                break;
            default:
                return $list;
        }

        return $list;

    }

    /***
     * 获取行情数据
     * @notes:
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @author: 小谢
     * @date: 2024/9/11 19:46
     */
    public function getMarketInfo()
    {
        $config=Config::get(1)->find();
        $list=Record::order(['id desc'])->limit(7)->field(['price','createtime'])->select();

        if(!empty($list)){
            $list = collection($list)->toArray();
            $list = array_reverse($list);
        }
        $categoriesArr =  array_column($list,'createtime');
        $categories = [];
        foreach ($categoriesArr as $v){
            $categories[] = date('m-d',strtotime($v));
        }
        $serles =[
            json_encode(['name'=>'走势图','data'=>array_column($list,'price')])
        ];

        $data=[
            'categories'=>$categories,
            'cny_price'=>$config['current_price'],
            'serles'=>$serles,
            'residue_account'=>$config['total_number']-$config['released'],
            'release_account'=>$config['released'],
            'destruction_account'=>$config['destroyed']
        ];
        return $data;

    }

    /***
     * 交易处理
     * @notes:
     * @param $user
     * @param $param
     * @return string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @author: 小谢
     * @date: 2024/9/11 16:40
     */
    public function tradeSubmit($user,$param)
    {

        if ($user->rep_password != md5(md5($param['rep_password']) . $user->salt)) {
            error_stop('支付密码错误！');
        }

        $teade=$this->query->where(['order_num'=>$param['order_num'],'status'=>0])->where('buy_uid|sale_uid','<>',$user->id)->lock(true)->find();
        if(empty($teade)){
            error_stop('订单错误！');
        }
        Db::startTrans();

        try{
            if($teade['type']==='buy'){
                if($teade['account']>$user->tokens){
                    throw new Exception('您的通证数量似乎不够！');
                }
                $teade->sale_uid=$user->id;
                $teade->pay_time=date('Y-m-d H:i:s');
                $teade->status=1;
                if($teade->save()){
                    WalletService::change( $user->id,'tokens',-$teade['account'],'transaction_sell');
                    WalletService::change( $teade->buy_uid,'tokens',$teade['account'],'transaction_buy');
                    $tt = "commission";
                    if ($teade->wallet_type == "gold_bean") {
                        $tt = "gold_bean";
                    }
                    WalletService::change( $user->id,$tt,$teade['actual_pay'],'transaction_income');
                }
            }elseif ($teade['type']==='sell'){
                $str = "福利券";
                $tt = "commission";
                if ($teade->wallet_type == "gold_bean") {
                    $tt = "gold_bean";
                    $str = "金豆";
                }
                if($teade['actual_pay']>$user->{$tt}){
                    throw new Exception("您的{$str}数量似乎不够！");
                }
                $teade->buy_uid=$user->id;
                $teade->pay_time=date('Y-m-d H:i:s');
                $teade->status=1;
                if($teade->save()){
                    WalletService::change( $user->id,$tt,-$teade['actual_pay'],'transaction_exp');
                    WalletService::change( $user->id,'tokens',$teade['account'],'transaction_buy');
                    WalletService::change( $teade->sale_uid,$tt,$teade['actual_pay'],'transaction_income');
                }
            }
            Db::commit();
            return 'ok';
        }catch (\Exception $e){
            Db::rollback();
            return $e->getMessage();
        }


    }


    /***
     * 取消订单
     * @notes:
     * @param $user
     * @param $param
     * @return string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @author: 小谢
     * @date: 2024/9/11 16:55
     */
    public function closeSubmit($user,$param)
    {
        if ($user->rep_password != md5(md5($param['rep_password']) . $user->salt)) {
            error_stop('支付密码错误！');
        }
        $teade=$this->query->where(['order_num'=>$param['order_num'],'buy_uid|sale_uid'=>$user->id,'status'=>0])->lock(true)->find();
        if(empty($teade)){
            error_stop('订单错误！');
        }

        Db::startTrans();
        try{
            if($teade['buy_uid']==$user->id){
                $teade->status=2;
                if($teade->save()){
                    $tt = "commission";
                    if ($teade->wallet_type == "gold_bean") {
                        $tt = "gold_bean";
                    }
                    WalletService::change( $user->id,$tt,$teade->actual_pay,'transaction_close');
                }
            }elseif($teade['sale_uid']==$user->id){
                $teade->status=2;
                if($teade->save()){
                    WalletService::change( $user->id,'tokens',$teade->account,'transaction_close');
                }
            }
           Db::commit();
            return 'ok';
        }catch (\Exception $e){
            Db::rollback();
            return $e->getMessage();
        }
    }


    public function autoCloseTrade()
    {
        $time = date("Y:m:d H:i:s", time() - 86400 * 3);

        $list = $this->query->where('status', 0)->where('createtime', '<=', $time)->select();

        if (!empty($list)) {
            foreach ($list  as $item) {
                if ($item['type'] == "buy") {
                    $item->status=2;
                    if($item->save()){
                        $tt = "commission";
                        if ($item->wallet_type == "gold_bean") {
                            $tt = "gold_bean";
                        }
                        WalletService::change( $item->buy_uid,$tt,$item->actual_pay,'transaction_auto_close');
                    }
                } else {
                    $item->status=2;
                    if($item->save()){
                        WalletService::change( $item->sale_uid,'tokens',$item->account,'transaction_auto_close');
                    }
                }
            }
        }

        return 'ok';
    }

    /***
     * 发布交易
     * @notes:
     * @param $user
     * @param $param
     * @return string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @author: 小谢
     * @date: 2024/9/11 18:07
     */
    public function openSubmit($user,$param)
    {
        if ($user->rep_password != md5(md5($param['rep_password']) . $user->salt)) {
            error_stop('支付密码错误！');
        }
        if($param['number']<=0 || $param['price']<=0){
            error_stop('参数错误！');
        }

        $tokenConfig=Config::get(1);
        $str = "福利券";
        $mul = 2.5;
        if ($param['walletType'] == "gold_bean") {
            $str = "金豆";
            $mul = 1;
        }
/*        if($tokenConfig->current_price>$param['price']){
            error_stop('当前行情价：'.$tokenConfig->current_price."{$str}，不能低于当前价格！");
        }*/

        Db::startTrans();
        try{
            $user=User::where('id',$user->id)->lock(true)->find();
            if($param['type']==='buy'){
                $money=bcmul($param['number'],$param['price']*$mul,3);
                if ($param['walletType'] == "commission") {
                    if($money>$user->commission){
                        throw new Exception("{$str}不足！");
                    }
                } else {
                    if($money>$user->gold_bean){
                        throw new Exception("{$str}不足！");
                    }
                }

                $this->query->save([
                    'order_num'=>'GT'.get_sn($user->id),
                    'buy_uid'=>$user->id,
                    'account'=>$param['number'],
                    'price'=>$param['price'],
                    'total_price'=>bcmul($param['number'],$param['price'],2),
                    'actual_pay'=>$money,
                    'type'=>$param['type'],
                    'createtime'=>date("Y-m-d H:i:s",time()),
                    "wallet_type" => $param['walletType']
                ]);
                WalletService::change( $user->id,$param['walletType'],-$money,'transaction_exp');
            }elseif ($param['type']==='sell'){

                if($user->tokens<$param['number']){
                    throw new Exception('通证不足！');
                }
                $money=bcmul($param['number'],$param['price']*$mul,3);
                $this->query->save([
                    'order_num'=>'GT'.get_sn($user->id),
                    'sale_uid'=>$user->id,
                    'account'=>$param['number'],
                    'price'=>$param['price'],
                    'total_price'=>bcmul($param['number'],$param['price'],2),
                    'actual_pay'=>$money,
                    'type'=>$param['type'],
                    'createtime'=>date("Y-m-d H:i:s",time()),
                    "wallet_type" => $param['walletType']
                ]);
                WalletService::change( $user->id,'tokens',-$param['number'],'transaction_sell');
            }
            Db::commit();
            return 'ok';
        }catch (\Exception $e){
            Db::rollback();
            return $e->getMessage();
        }

    }


}